require "Util.BaseClassHelper"
--Lua5.1 __gc方法（Lua5.2开始才支持直接设置__gc）
function setmt__gc(t, mt)
  local prox = newproxy(true)
  getmetatable(prox).__gc = function() mt.__gc(t) end
  t[prox] = true
  return setmetatable(t, mt)
end

--每个对象的唯一标志
G_obj_unique_id = G_obj_unique_id or 0

local _class = {}
function BaseClass(super)
    
        local class_type = {}
        
        local vtbl = {} -- construct virtual table
        _class[class_type] = vtbl
            
        local info = debug.getinfo(2, "Sl")
	    class_type._source = info.source
	    class_type._cline =  info.currentline
        class_type.__init = false
	    class_type.__delete = false
        class_type.super = super
        
        function class_type.New (_, ...)  -- Add by liboxiang 
                G_obj_unique_id = G_obj_unique_id + 1
                local obj = {_class_type=class_type, _obj_unique_id = G_obj_unique_id}

                --__gc方法
                local meta_table = {__index = vtbl,
                                    --__newindex = BaseClassHelper.NewIndex,
                                    __tostring = function(target)
								        return string.format("lua[DeleteMe():%s,source:%s,line:%d,uid:%d]", target._use_delete_method and "true" or "false", target._class_type._source, target._class_type._cline, target._obj_unique_id)
							        end,
                                    __gc = function(target) 
                                    		   if target._use_delete_method then
                                                   print("_use_delete_method __gc=>", target)
                                                   return
		                                        else
                                                    print("__gc=>", target)
                                                end
                                                --target._use_delete_method = true
                                                do
                                                    local decreate -- a function use for recursion to base class
                                                    decreate = function(c)
                                                        if c.__delete then
                                                            c.__delete(target) 
                                                        end

                                                        if c.super then
                                                            decreate(c.super)
                                                        end
                                                    end
                        
                                                    decreate(target._class_type)
                                                end
                                    end
                }

                --為了可以在 class:ctor()函數里 ，可以冒號調用self:func()，放到這裡來
               -- setmetatable(obj, {__index=vtbl})
                setmetatable(obj, meta_table)

                do
                    local create -- a function use for recursion to super class
                    
                    create = function(c, ...)
                        if c.super then
                            create(c.super, ...)
                        end
                        if c.__init then
                            c.__init(obj, ...) 
                        end

                    end
                    
                    create(class_type, ...)
                end

                return obj
        end
          
        setmetatable(class_type, {__newindex=
            function(t, k, v)
                vtbl[k] = v
            end,
            __index = function (t, k)
                return vtbl[k]
            end,
            __call = class_type.New
            }
        )

        if super then
            setmetatable(vtbl, {__index = function(t, k)
                    --print("--" .. tostring(t) .. " k:" .. tostring(k))
                    local ret=_class[super][k] --为了追溯父类的成员
                    vtbl[k]=ret
                    return ret
                end}
            )
        else
            --GetWeak是用来解除循环强引用的
            --为了兼容旧的框架才有DeleteMe、Instantiate 方法
            local meta_table_for_vtbl = {__index={GetWeak=BaseClassHelper.GetWeak, DeleteMe=BaseClassHelper.DeleteMe, Instantiate=BaseClassHelper.Instantiate}}
            setmetatable(vtbl, meta_table_for_vtbl)
        end
        
        return class_type
end

function ExtendClass(super)
    if not super then
        error("Can not find super")
    end
    return BaseClass(super)
end